﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Model;
using DataAccess.EntityFramework;
using Lib.Query;
using DataAccess.NHibernate;
using Model.IRepository;
using Model.Queries;
using System.IO;
using System.Xml.Serialization;

namespace Test
{
    [TestClass]
    public class PolicyRepositoryTest
    {
        IPolicyRepository repository;
        string orm = "NHibernate";

        [TestInitialize()]
        public void InitContext()
        {
            NHSessionFactory.Init();

            if(orm == "EntityFramework")
                repository = new DataAccess.EntityFramework.PolicyRepository();
            else
                repository = new DataAccess.NHibernate.PolicyRepository();
        }

        [TestMethod]
        public void Select_All_Policies()
        {            
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            IList<Policy> list = repository.FindBy<Policy>(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
        }

        [TestMethod]
        public void Select_Top_All_Policies()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Top(2);
            IList<Policy> list = repository.FindBy<Policy>(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(2, list.Count);
        }

        [TestMethod]
        public void Select_Equal_Policy_By_Number()
        {         
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Add(x => x.Number, CriteriaOperator.Equal, (long)1);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(1, list[0].Id);
        }

        [TestMethod]
        public void Select_NotEqual_Policy_By_Number()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Add(x => x.Number, CriteriaOperator.NotEqual, (long)1);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(2, list.Count);
            Assert.AreEqual(2, list[0].Id);
            Assert.AreEqual(3, list[1].Id);
        }

        [TestMethod]
        public void Select_Or_2_Policies_By_Number()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Operator(QueryOperator.Or);
            query.Add(x => x.Number, CriteriaOperator.Equal, (long)1);
            query.Add(x => x.Number, CriteriaOperator.Equal, (long)2);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(2, list.Count);            
        }

        [TestMethod]
        public void Select_And_2_Policies_By_Number()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Operator(QueryOperator.And);
            query.Add(x => x.Number, CriteriaOperator.Equal, (long)1);
            query.Add(x => x.Number, CriteriaOperator.Equal, (long)2);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(0, list.Count);
        }

        [TestMethod]
        public void Select_Equal_Policy_By_PersonName()
        {            
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Add(x => x.Person.Name, CriteriaOperator.Equal, "Name2");

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(3, list[0].Id);
        }

        [TestMethod]
        public void Select_Like_Policies_By_PersonName()
        {         
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Add(x => x.Person.Name, CriteriaOperator.Like, "Name2");

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(3, list[0].Id);

            query = new LiteQuery<Policy>();
            query.Add(x => x.Person.Name, CriteriaOperator.Like, "Name");

            list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);            
        }

        [TestMethod]
        public void Select_Like_With_Top_Policies_By_PersonName()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Top(2);
            query.Add<Policy>(x => x.Person.Name, CriteriaOperator.Like, "Name");

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(2, list.Count);
        }

        [TestMethod]
        public void Select_Inheritance_All_MotorPolicies()
        {            
            LiteQuery<MotorPolicy> query = new LiteQuery<MotorPolicy>();            
            query.Add(x => x.PlateNo, CriteriaOperator.Equal, "PlateNo2");
            IList<MotorPolicy> list = repository.FindBy<MotorPolicy>(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual("PlateNo2", list[0].PlateNo);
            Assert.AreEqual(2, list[0].Id);
        }

        [TestMethod]
        public void Select_Order_Ascending_And_Descending_All_Polcies_By_Policy_Number()
        {            
            //ASC
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Number, true);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(1, list[0].Id);

            //DESC
            query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Number, false);

            list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(3, list[0].Id);
        }

        [TestMethod]
        public void Select_Order_Ascending_And_Descending_All_Polcies_By_PersonName()
        {            
            //ASC
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Person.Name, true);

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(1, list[0].Id);

            //DESC
            query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Person.Name, false);

            list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(2, list[0].Id);
        }

        [TestMethod]
        public void Select_PredefinedQuery_Equal_Policy_By_Number()
        {
            PolicyQuery query = new PolicyQuery();
            query.Number = 2;

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(2, list[0].Id);
        }

        [TestMethod]
        public void Select_PredefinedQuery_Like_PersonName()
        {
            PolicyQuery query = new PolicyQuery();
            query.PersonName = "Name2";

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(3, list[0].Id);
        }

        [TestMethod]
        public void Select_PredefinedQuery_And_Like_PersonName_And_Equal_Number()
        {
            PolicyQuery query = new PolicyQuery();
            query.PersonName = "Name3";
            query.Number = 2;

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(2, list[0].Id);
        }

        [TestMethod]
        public void Select_PredefinedQuery_Or_Like_PersonName_And_Equal_Number()
        {
            PolicyQuery query = new PolicyQuery();
            query.PersonName = "Name3";
            query.Number = 1;
            query.OrderBy(x => x.Id, true);
            query.Operator(QueryOperator.Or);                        

            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(2, list.Count);
            Assert.AreEqual(1, list[0].Id);
            Assert.AreEqual(2, list[1].Id);
        }

        [TestMethod]
        public void Select_PredefinedQuery_Child_Like_PlateNo()
        {
            MotorPolicyQuery query = new MotorPolicyQuery();
            query.PlateNo = "PlateNo3";
              
            IList<Policy> list = repository.FindBy<Policy>(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(3, list[0].Id);            
        }

        [TestMethod]
        public void Select_WCF_Policy_By_Id()
        {
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.Add(x => x.Id, CriteriaOperator.Equal, 1);

            Test.PolicyServiceReference.PolicyServiceClient client = new PolicyServiceReference.PolicyServiceClient();                                 
            IList<Policy> list =  client.FindBy(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(1, list[0].Id);
        }

        [TestMethod]
        public void Select_WCF_PredefinedQuery_Policy_By_Id()
        {
            PolicyQuery query = new PolicyQuery();
            query.Id = 1;

            Test.PolicyServiceReference.PolicyServiceClient client = new PolicyServiceReference.PolicyServiceClient();
            IList<Policy> list = client.FindByPredefined(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(1, list[0].Id);
        }

        [TestMethod]
        public void Select_WCF_PredefinedQuery_MotorPolicy_By_PlateNo()
        {
            MotorPolicyQuery query = new MotorPolicyQuery();
            query.PlateNo = "PlateNo3";

            Test.PolicyServiceReference.PolicyServiceClient client = new PolicyServiceReference.PolicyServiceClient();
            IList<Policy> list = client.FindByPredefined(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(3, list[0].Id);
        }

        [TestMethod]
        public void Select_WCF_PredefinedQuery_OrderBy()
        {
            PolicyQuery query = new PolicyQuery();
            query.OrderBy(x => x.Number, true);

            Test.PolicyServiceReference.PolicyServiceClient client = new PolicyServiceReference.PolicyServiceClient();
            IList<Policy> list = client.FindByPredefined(query);

            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(1, list[0].Id);
        }

        [TestMethod]
        public void Select_WCF_Order_Ascending_And_Descending_All_Polcies_By_PersonName()
        {
            //ASC
            LiteQuery<Policy> query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Person.Name, true);

            Test.PolicyServiceReference.PolicyServiceClient client = new PolicyServiceReference.PolicyServiceClient();

            IList<Policy> list = client.FindBy(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(1, list[0].Id);

            //DESC
            query = new LiteQuery<Policy>();
            query.OrderBy(x => x.Person.Name, false);

            list = client.FindBy(query);
            Assert.IsNotNull(list);
            Assert.AreEqual(3, list.Count);
            Assert.AreEqual(2, list[0].Id);
        }

        [TestMethod]
        public void Serialize_To_String()
        {
            PolicyQuery query = new PolicyQuery();
            XmlSerializer serializer;
            serializer = new XmlSerializer(query.GetType());                
            StringWriter sw = new StringWriter();
            serializer.Serialize(sw, query);
            string xml = sw.ToString();

            Assert.IsNotNull(xml);
        }
    }
}